//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <bsp.h>
#include <mmu.h>
#include <init.h>
//#include <lcd.h>
//#include "font.h"

//const uint8_t c_u8DefaultColor  = 0xf;
//const uint_t c_uTabStopValue    = 8;
//
//EXTERN_C DECL_CODEINIT bool_t CDECL InitScreen();

EXTERN_C void PrintComPort(const char *szMessage);

//STATIC bool_t s_bScreenInited = FALSE;
STATIC bool_t s_bComPortInited = FALSE;

EXTERN_C DECL_CODEINIT bool_t CDECL InitConsole()
{
//    s_bScreenInited = InitScreen();
//    if (!s_bScreenInited) return FALSE;
//
//    BspClearScreen();

    if (!s_bComPortInited) {
        s_bComPortInited = BspSetupComPort(COMPORT_PRINT, NULL);
    }

    return s_bComPortInited;
}

EXTERN_C void CDECL BspWriteConsole(const char *szMessage)
{
    if (NULL == szMessage) return;

//    if (s_bScreenInited) BspPrintScreen(szMessage);

    if (!s_bComPortInited) {
        s_bComPortInited = BspSetupComPort(COMPORT_PRINT, NULL);
    }

    if (s_bComPortInited) PrintComPort(szMessage);
}

EXTERN_C void PrintComPort(const char *szMessage)
{
    assert(szMessage);

    for (const char *pc = szMessage; '\0' != *pc; pc++) {
        BspWriteComPort(COMPORT_PRINT, *pc);
    }
}

//EXTERN_C DECL_CODEINIT bool_t CDECL InitScreen()
//{
//    // Set the palette to be a 1-to-1 mapping of the pixel vaules
//    Outl(PALLSW, 0x76543210);
//    Outl(PALMSW, 0xfedcba98);
//
//    // Set video buffer size = (total bits in video buffer / 128) - 1
//    const uint_t c_uVideoBufferSize =
//        ((c_uLCDNumberOfPixels * c_uLCDBitsPerPixel) / 128) - 1;
//
//    // Set line length = (number of pixels in line / 16) - 1
//    const uint_t c_uLineLength = (c_uLCDPixelsPerRow / 16) - 1;
//
//    const uint_t c_uLCDConfig =
//        __GSMD | __GSEN | (13 << __AC_PRESCALE_SHIFT)
//        | (__PIXEL_PRESCALE << __PIXEL_PRESCALE_SHIFT)
//        | (c_uLineLength << __LINE_LENGTH_SHIFT) | c_uVideoBufferSize;
//
//    Outl(LCDCON, c_uLCDConfig);
//
//    // Set the start address for the LCD Frame Buffer
//    Outb(FBADDR, c_paLCDFrameBufferStartAddr >> 28);
//
//    SetVEE(120); // Set LCD 21V (arrange: 0 - 255)
//
//    EnableLCD();
//
//    SetLCDELEn();
//
//    return TRUE;
//}
//
//STATIC uint_t s_uCursorLocation = 0;
//
//STATIC void PrintChar(char ch, uint_t uLocation, uint8_t u8Color);
//
//INLINE void SetCursorLocation(uint_t uCursorLocation)
//{
//    PrintChar('_', uCursorLocation, c_u8DefaultColor);
//}
//
//INLINE void ClearCursorLocation(uint_t uCursorLocation)
//{
//    PrintChar(' ', uCursorLocation, c_u8DefaultColor);
//}
//
//EXTERN_C void CDECL BspClearScreen()
//{
//    register uint8_t *p = (uint8_t *)VIRTADDR(c_paLCDFrameBufferStartAddr);
//
//    for (uint_t i = 0; i < c_uLCDFrameBufferSize; i++) {
//        p[i] = 0;
//    }
//
//    s_uCursorLocation = 0;
//    SetCursorLocation(s_uCursorLocation);
//}
//
//STATIC void PrintChar(char ch, uint_t uLocation, uint8_t u8Color)
//{
//    if (128 < ch) ch = ' ';
//
//    uint_t uCharRow     = uLocation / c_uLCDCharsPerRow;
//    uint_t uCharColumn  = uLocation % c_uLCDCharsPerRow;
//
//    uint8_t *p =
//        (uint8_t *)VIRTADDR(c_paLCDFrameBufferStartAddr)
//        + uCharRow * c_uLCDBytesPerCharRow;
//
//    const uint_t c_uBytesPerFontRow = c_uFontWidth * c_uLCDBitsPerPixel / 8;
//
//    uint8_t fontRowBuf[c_uBytesPerFontRow];
//    for (uint_t i = 0; i < c_uFontHeight; i++) {
//        uint8_t u8FontRowData = c_u8FontData[(ch << 3) + i];
//
//        for (uint_t j = 0; j < c_uBytesPerFontRow; j++, u8FontRowData <<= 1) {
//            fontRowBuf[j] = (u8FontRowData & 0x80)? (u8Color & 0x0f) : 0;
//            u8FontRowData <<= 1;
//            fontRowBuf[j] |= (u8FontRowData & 0x80)? u8Color << 4 : 0;
//        }
//
//        memcpy(
//            p + i * c_uLCDBytesPerRow + uCharColumn * c_uBytesPerFontRow,
//            fontRowBuf, c_uBytesPerFontRow);
//    }
//}
//
//EXTERN_C void CDECL BspPrintScreen(const char *szMessage)
//{
//    assert(szMessage);
//
//    ClearCursorLocation(s_uCursorLocation);
//
//    for (const char *pc = szMessage; '\0' != *pc; pc++) {
//        switch (*pc) {
//        case '\a':
//            BspBeep();
//            break;
//
//        case '\b':
//            if (0 == s_uCursorLocation) break;
//
//            s_uCursorLocation--;
//            PrintChar(' ', s_uCursorLocation, c_u8DefaultColor);
//
//            ClearCursorLocation(s_uCursorLocation);
//            break;
//
//        case '\n':
//            s_uCursorLocation += c_uLCDCharsPerRow;
//            // no break statement! Need translate LF to CRLF.
//
//        case '\r':
//            s_uCursorLocation -= s_uCursorLocation % c_uLCDCharsPerRow;
//            break;
//
//        case '\t':
//            do {
//                PrintChar(' ', s_uCursorLocation, c_u8DefaultColor);
//                s_uCursorLocation++;
//            } while (s_uCursorLocation % c_uTabStopValue);
//            break;
//
//        default:
//            PrintChar(*pc, s_uCursorLocation, c_u8DefaultColor);
//            s_uCursorLocation++;
//        } // switch
//
//        // Need Scroll ?
//        if (s_uCursorLocation
//            >= c_uLCDCharsPerRow * (c_uLCDCharsPerColumn - 1)) {
//            uint8_t *p = (uint8_t *)VIRTADDR(c_paLCDFrameBufferStartAddr);
//            memcpy(
//                p, p + c_uLCDBytesPerCharRow,
//                (c_uLCDCharsPerColumn - 1) * c_uLCDBytesPerCharRow);
//
//            for (uint_t i = c_uLCDCharsPerRow * (c_uLCDCharsPerColumn - 1);
//                 i < c_uLCDCharsPerRow * c_uLCDCharsPerColumn; i++) {
//                PrintChar(' ', i, c_u8DefaultColor);
//            }
//
//            s_uCursorLocation -= c_uLCDCharsPerRow;
//        }
//    }
//
//    SetCursorLocation(s_uCursorLocation);
//}
